#include "KcpSender.h"
#include <cstring>

KCPSender::KCPSender()
:m_IsRunning(false), m_RingFlow(NULL), m_Buffer(NULL)
{

}

KCPSender::~KCPSender()
{
    printf("KCPSender destruct\n");
    if (m_RingFlow != NULL) {
        rbuf_destroy(m_RingFlow);
        m_RingFlow = NULL;
    }
    if (m_Buffer != NULL) {
        delete[] m_Buffer;
        m_Buffer = NULL;
    }
}

int KCPSender::InitSender(const char* local_ip, int local_port, const char* remote_ip, int remote_port)
{
    int ret = 0;
    KcpPeerConfig config;
    strcpy(config.local_ip, local_ip);
    config.local_port = local_port;
    strcpy(config.remote_ip, remote_ip);
    config.remote_port = remote_port;
    ret = PeerCreate(config);
    if (ret != 0) {
        printf("PeerCreate failed\n");
        return -1;
    }

    m_Buffer = new char[1500];
    m_RingFlow = rbuf_create(NULL, 1500, 512, RBUF_MODE_SIMPLE, 0);
    if (m_RingFlow == NULL) {
        printf("rbuf_create failed\n");
        return -1;
    }

    if (pthread_create(&m_Thread_id, NULL, SendDataThread, (void *)this) != 0)
    {
        printf("Could not start send data thread\n");
		return -1;
	}

    return 0;
}

void KCPSender::Close()
{
    if (m_IsRunning)
    {
        m_IsRunning = false;
        pthread_join(m_Thread_id, NULL);
    }
}

void* KCPSender::SendDataThread(void *arg)
{
    int ret = 0, post = -1;
    KCPSender* sender = (KCPSender*)arg;
    sender->m_IsRunning = true;
    char* sendData = sender->m_Buffer;
    int snd_cnt = PACKET_SEND_MAX_COUNT;
    
    while (sender->m_IsRunning)
    {
        snd_cnt = PACKET_SEND_MAX_COUNT;
        sender->KcpSync();
        do
        {
            ret = rbuf_read_post(sender->m_RingFlow, sender->m_Buffer, 1500, &post);
            if (ret > 0) {
                int send_ret = sender->SendKcpData(sender->m_Buffer, ret);
                if (snd_cnt-- == 0) {
                    break;
                }
            }
        } while (ret > 0);
        usleep(1 * 1000);
    }
    
    return NULL;
}